package com.xbn.netty.nettyGroupChat;

import io.netty.channel.Channel;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.SimpleChannelInboundHandler;
import io.netty.channel.group.ChannelGroup;
import io.netty.channel.group.DefaultChannelGroup;
import io.netty.util.CharsetUtil;
import io.netty.util.concurrent.GlobalEventExecutor;

import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.Map;


/**
 * @author XBN
 * @date 2020/10/21 14:39
 * @email 78742541@qq.com
 */
public class GroupChatServerHandler extends SimpleChannelInboundHandler<String> {
    //定义一个chanel组，管理所有的channel
    //GlobalEventExecutor.INSTANCE指的是全局事件执行器，是一个单例，
    private static ChannelGroup channelGroup=new DefaultChannelGroup(GlobalEventExecutor.INSTANCE);
    SimpleDateFormat sdf= new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    //当连接建立的时候第一个被调用的方法
    @Override
    public void handlerAdded(ChannelHandlerContext ctx) throws Exception {
        Channel channel = ctx.channel();
        //将该用户上线的信息推送给其它在线的用户
        //该方法会向channelGroup中的所有channel发送信息，从而实现给所有客户端发送信息
        channelGroup.writeAndFlush("[客户端]"+channel.remoteAddress()+" 加入了聊天,当前在线用户个数:"+channelGroup.size());
        //将当前的channel加入到channelGroup
        channelGroup.add(channel);

        super.handlerAdded(ctx);
    }
    //客户端断开连接的时候会调用该方法
    @Override
    public void handlerRemoved(ChannelHandlerContext ctx) throws Exception {
        //将xx用户下线的信息推送给所有其它在线的用户
        channelGroup.writeAndFlush("用户"+ctx.channel().remoteAddress()+"下线了,当前在线用户个数:"+channelGroup.size());
    }

    //表示channel处理活动的状态(已经完成了连接了)，提示xx上线，主要是在服务器端提示xxx上线
    @Override
    public void channelActive(ChannelHandlerContext ctx) throws Exception {
        System.out.println(ctx.channel().remoteAddress()+"上线了");
        System.out.println("当前在线用户个数:"+channelGroup.size());
    }
        //该方法会在channel处于非活动状态的时候触发
    //提示xxx离线了
    @Override
    public void channelInactive(ChannelHandlerContext ctx) throws Exception {
        System.out.println(ctx.channel().remoteAddress()+"下线了");
        System.out.println("当前在线用户个数:"+channelGroup.size());
    }
    //读取数据，并且将读取到的数据转发给当前在线的所有的用户
    @Override
    protected void channelRead0(ChannelHandlerContext channelHandlerContext, String s) throws Exception {
        //获取到当前的channel
        Channel channel = channelHandlerContext.channel();
        //我们要排除掉自身
        for (Channel ch : channelGroup) {
            if(ch!=channel )
            {
                //如果遍历到的channel不是当前用户的channel，那么我们就需要进行消息的转发
                ch.writeAndFlush("[用户]"+channel.remoteAddress()+":"+s+"\n");
            }
            else {
                ch.writeAndFlush("您发送的消息已经成功推送给其它成员了");
            }
        }
    }

    @Override
    public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause) throws Exception {
        //关闭通道
        ctx.close();
    }
}
